"use strict";
/*
 * @Author: quit
 * @Date: 2023-03-13 05:04:04
 * @LastEditTime: 2023-03-17 02:46:09
 * @Descripttion: 接口的概念
 * 是对行为的抽象,而具体任何行动需要由类(classes)去实现
 * 在TS中,我们由接口(interfaces)来定义对象的类型,除了可用于对类的一部分行为进行抽象以外(这就是将多个类公共的属性和方法抽离为一个接口在由类去实现),也常用与对【 对象的形状(Shape) 】进行描述
 * @notice:
 */
Object.defineProperty(exports, "__esModule", { value: true });
// let v1: number = 10;
// let v2 = {};
// interface Animal {
//     color: string;
//     height: number;
// }
// let v3: Animal;
// v3 = {
//     color: 'yellow',
//     height: 50
// };
/**
 * @description: 可选属性和只读属性
 * 有时我们希望不要完全匹配一个形状,那么可以用可选属性
 * const、readonly 变量声明选择 const 属性声明选择readonly
 * 在定义时在变量添加?表示当前变量为可选属性
 * 不可添加在接口中不存在的属性
 */
// interface Animal {
//     readonly color: string;
//     height: number;
//     foot?: boolean;
// }
// let v1: Animal = {
//     color: 'yellow',
//     height: 200,
//     foot: true
// };
// // v1.color = '123'; 添加readonly的属性,在初始化赋值后不可以修改与const 声明的变量相同
// let v2: Animal = {
//     color: 'flower',
//     height: 15,
//     foot: false
// };
// let v3: Animal = {
//     color: 'flower',
//     height: 15
// };
// console.log(v1, v2, v3);
/**
 * @description: 任意属性
 * 一个接口可能需要它除了具有我们需要的属性,还可以包含任意的其他属性
 * 只要使用了任意属性,就要保证 确定属性和可选属性的类型都必须是它的类型的子集
 */
// interface Animal {
//     color: string;
//     height: number;
//     foot?: boolean;
//     // [propName: string]: string | number | boolean; // 类似于函数的形参,值表示为对象的索引,也表示索引签名的意思 ; 这里确保已存在的成员类型
//     [propName: string]: any;
// }
// let v1: Animal = {
//     color: 'yellow',
//     height: 500,
//     foot: true,
//     x: 12, // 在实际使用时可能存在多种数据与未预期的数据
//     y: '',
//     z: false
// };
/**
 * @description: 函数类型
 * 接口能描述TS中对象拥有的各种外形,除了描述带有属性的普通对象外,接口也可以描述函数类型
 * 函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的
 */
// let add: Function = function (x: number, y: string): string {
//     return x.toString() + y;
// };
// // 一下为TS中的函数定义,并不是JS中的箭头函数
// let add1: (x: number, y: string) => string;
// add1 = function (x: number, y: string): string {
//     return x.toString() + y;
// };
// console.log(add(1, '--'), add1(2, '--'));
// interface MyFn {
//     (x: number, y: string): string;
// }
// let add2: MyFn;
// add2 = function (x: number, y: string): string {
//     return x.toString() + y;
// };
// console.log(add2(3, '--'));
/**
 * @description: 可索引属性
 * 已使用函数接口差不多,我们也可以描述那些能够"通过索引得到"的类型,比如 arr[index],obj[nodeName]
 * 可索引类型具有一个 索引签名 ,它描述了对象索引的类型,还有相应的索引返回值类型
 * TS支持两种索引签名, 字符串和数字,可同时使用,但要注意 '数字类型索引的返回值是字符串索引返回值类型的子类型或者一致';
 * 因为当使用 number 来索引时JS会将它转为 string 然后再去索引对象,即obj[100] == obj['100']
 */
// interface MyIndex {
//     [index: number]: number;
// }
// let i1: MyIndex = [1, 2, 3]; // index = 0（number） 返回值是 1（number）
// let i2: MyIndex = { 0: 1, 1: 2, 2: 3 };
// interface MyIndex {
//     [index: string]: number;
// }
// let i1: MyIndex = [1, 2, 3]; // error
// let i2: MyIndex = { '0': 1, '1': 2, '2': 3 };
// class Animal {
//     color: string;
// }
// class Dog extends Animal {
//     foot: boolean;
// }
// let c1: Dog = new Dog();
// let c2: Animal = new Animal();
// interface MyIndex {
//     [index: number]: Dog;
//     [index: string]: Animal;
// }
// let i1: MyIndex = {
//     0: c1,
//     a: c2
// };
// console.log(i1);
/**
 * @description: 接口继承接口 extends
 * 和类一样,接口也可以相互继承,这让我们能够从一个接口复制成员到另一个接口中,可以更灵活的将接口分割到重用模块里,进而实现低耦合高类聚的理念
 */
// interface Animal {
//     color: string;
// }
// interface Dog {
//     bodyLength: number;
// }
// interface GreyDog extends Dog, Animal {
//     only: Boolean;
// }
// let v1: GreyDog = {
//     color: 'grey',
//     bodyLength: 50,
//     only: true
// };
// console.log(v1);
/**
 * @description: 接口继承类
 * 当接口继承了一个类型时,它会继承类的成员但'不包括其实现';就像接口声明了所有类中存在的成员,但并没有提供具体实现
 * 类定义会创建两个东西: 类的实例类型和一个构造函数.因为类可以创建出类型,所以可以在接口中使用类
 */
class Animal {
    move() {
        console.log('Animal Handle');
    }
}
let v1 = {
    bodyLength: 500,
    color: 'grey',
    move() {
        console.log('v1 -- Dog');
    }
};
console.log(v1);
v1.move();
